/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


var savefileto =
{
    get mode()   { return document.getElementById("mode"); },
    get radio()  { return document.getElementById("savefileto-radio"); },
    get button() { return document.getElementById("savefileto-button"); },
    get save()   { return document.getElementById("savefileto-save-button"); },
    
    get selected()      { return this.radio.selected; },
    set selected(value) { this.mode.selectedItem = this.radio; },
    
    get folder() { return this._folder; },
    set folder(value)
    {
        this._folder = value;
        this.save.disabled = (! value);
    },
    
    onLoad: function()
    {
        Components.utils.import("resource://gre/modules/DownloadPaths.jsm", this);
        Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm", this);
        
        Components.utils.import("resource://savefileto/common.jsm", this);
        Components.utils.import("resource://savefileto/DataSource.jsm", this);
        Components.utils.import("resource://savefileto/savefileto.jsm", this);
        
        var self = this;
        
        var enabled = this.savefileto.prefs.fileEnabled;
        document.getElementById("savefileto-box").hidden = (! enabled);
        
        if (! enabled)
            return;
        
        // show normalBox instead of basicBox
        // idea copied from DownThemAll!
        // implementation is slightly different, so the actual result varies depending whose load handler is run first
        if (! document.getElementById("basicBox").collapsed)
        {
            document.getElementById("open").parentNode.collapsed = true;
            document.getElementById("basicBox").collapsed = true;
            document.getElementById("normalBox").collapsed = false;
        }
        
        this.filename = document.getElementById("location").getAttribute("realname");
        this.prompt = false;
        
        // init access key
        this._updateAccessKey();
        this.accessKeyChangeListener = function(prefs, propName) { if (propName == "fileAccessKey") self._updateAccessKey(); }
        this.savefileto.prefs.addListener(this.accessKeyChangeListener);
        
        // default to most recent folder if there is one
        this.folder = this.savefileto.getMostRecentFolder("file", window);
        this.button.label = (this.folder ? this.folder.label : "");
        
        // create cascade menu
        var commandCallback = function(e, folder) { self.onCommand(e, folder); }
        let options = {mainMenuPosition: "after_start"};
        let cascadeMenu = this.savefileto.createCascadeMenu(window, "file", commandCallback, options);
        cascadeMenu.attach(this.button);
        
        // select Save File to when button popup opened
        var menuPopup = this.button.firstChild;
        menuPopup.addEventListener("popupshowing", function() { self.selected = true; }, false);
        
        // pre and post mode select listeners
        document.addEventListener("select", function(e) { self.onBeforeModeSelect(e); }, true);
        //this.mode.addEventListener("select", function(e) { dump("mode select\n"); }, false);
        this.radio.addEventListener("RadioStateChange", function(e) { self.onAfterModeSelect(e); }, false);
        this.oldSelected = false;
        
        // dialog accept listener
        var oldValue = document.documentElement.getAttribute("ondialogaccept");
        var newValue = "if (savefileto.selected) return savefileto.onDialogAccept(); else { " + oldValue + " }";
        document.documentElement.setAttribute("ondialogaccept", newValue);
    },
    
    onUnload: function()
    {
        if (this.accessKeyChangeListener)
            this.savefileto.prefs.removeListener(this.accessKeyChangeListener);
    },
    
    onBeforeModeSelect: function(e)
    {
        if (e.target != this.mode)
            return;
        
        var selected = this.selected;
        if (selected || (selected == this.oldSelected))
            return;
        
        this._update();
    },
    
    onAfterModeSelect: function(e)
    {
        var selected = this.selected;
        if ((! selected) && (selected == this.oldSelected))
            return;
        
        this._update();
    },
    
    onCommand: function(e, folder)
    {
        this.folder = folder;
        this.prompt = e.ctrlKey;
        this.button.label = this.folder.pathLabel;
        
        this._update();
        
        if (this.savefileto.prefs.startDownloadOnSelect)
            document.documentElement.acceptDialog();
    },
    
    onSaveCommand: function(e)
    {
        this.selected = true;
        this.prompt = e.ctrlKey;
        
        this._update();
        document.documentElement.acceptDialog();
    },
    
    // http://mxr.mozilla.org/firefox/source/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in#850
    // http://mxr.mozilla.org/firefox/source/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in#506
    
    onDialogAccept: function()
    {
        var self = this;
        var launcher = dialog.mLauncher;
        var prompt = (this.prompt || this.savefileto.prefs.prompt);
        var folder = this.folder;
        var file = null;
        let context = dialog.mContext;
        
        if (! prompt)
        {
            file = folder.file.clone();
            file.append(this.filename);
            file = this.DownloadPaths.createNiceUniqueFile(file);
        }
        
        // clean up (from nsHelperAppDlg.js.in)
        launcher.setWebProgressListener(null);
        dialog.mDialog.dialog = null;
        
        // don't start downloading until dialog has closed
        var _saveToDisk = function() { self.callLater(0, self, self._saveToDisk, [launcher, prompt, folder, file, context]); };
        window.addEventListener("unload", _saveToDisk, false);
        
        return true;
    },
    
    _saveToDisk: function(launcher, prompt, folder, file, context)
    {
        var docUri = launcher.source;
        var privacyContext = this.PrivateBrowsingUtils.privacyContextFromWindow(context);
        var prefsBackup = this.savefileto.getDownloadPrefs(docUri, privacyContext);
        
        try
        {
            var prefs = {useDownloadDir: (! prompt), folderList: 2, dir: folder.file, lastDir: folder.file};
            var lastDownloadDir = {uri: docUri, file: folder.file};
            this.savefileto.setDownloadPrefs({downloadPrefs: prefs, lastDownloadDir: lastDownloadDir}, privacyContext);
            
            // saveToDisk() throws if its prompt dialog is cancelled - don't bother catching
            launcher.saveToDisk((prompt ? null : file), false);
            this.savefileto.addToRecent("file", folder, context);
        }
        finally
        {
            // restore original browser download preferences
            this.savefileto.setDownloadPrefs(prefsBackup, privacyContext);
        }
    },
    
    _updateAccessKey: function()
    {
        this.radio.accessKey = this.savefileto.prefs.fileAccessKey;
    },
    
    _update: function()
    {
        var selected = this.selected;
        var hasFolder = this.folder;
        
        this.oldSelected = selected;
        
        this.button.style.MozUserFocus = (selected ? "normal" : "ignore");
        this.save.style.MozUserFocus = (selected ? "normal" : "ignore");
        document.getElementById("openHandler").style.MozUserFocus = (selected ? "ignore" : "normal");
        document.getElementById("chooseButton").style.MozUserFocus = (selected ? "ignore" : "normal");
        document.getElementById("rememberChoice").disabled = selected;
        document.documentElement.getButton("accept").disabled = (selected && (! hasFolder));
    }
}


window.addEventListener("load", function() { savefileto.onLoad(); }, false);
window.addEventListener("unload", function() { savefileto.onUnload(); }, false);
